package com.pkk.penguin.frame.know.java.practice.stack.impl.linkedstack;

import com.pkk.penguin.frame.know.java.practice.stack.impl.StackInter;
import java.util.EmptyStackException;
import org.junit.Test;

/**
 * @description: 链表方式实现栈
 * @author: peikunkun
 * @create: 2020-01-03 16:46
 **/
public class SinglyLinkedListStack<T> implements StackInter<T> {


  @Test
  public void Administrator_14_20200103170608() {
    System.out.println("欢迎使用单元测试方法【Administrator_14()_20200103170608】");
    System.out.println("此方法测试描述：【】");
    final SinglyLinkedListStack<Object> linkedStack = new SinglyLinkedListStack<Object>();
    Node<Object> top = linkedStack.top;
    top = new Node<>("1", top);
    top = new Node<>("2", top);
    top = new Node<>("3", top);
    //3-top(2链相连)->2-top(1链相连)->1-top(初始化链相连)->null-null
    System.out.println(top);
  }


  /**
   * 栈顶指针
   */
  private Node<T> top;

  public SinglyLinkedListStack() {
    top = new Node<T>();
  }


  /**
   * @Description: 压栈
   * @Param: element
   * @return: boolean
   * @Author: peikunkun
   * @Date: 2020/1/3 0003 下午 4:28
   */
  @Override
  public boolean push(T element) {
    top = new Node<T>(element, top);
    return true;
  }

  /**
   * @Description: 弹栈
   * @return: T
   * @Author: peikunkun
   * @Date: 2020/1/3 0003 下午 4:29
   */
  @Override
  public T pop() {
    if (this.isEmpty()) {
      throw new EmptyStackException();
    }
    T result = top.item;
    //当子链还存在的时候,进行切换到下一个子链
    if (!top.end()) {
      top = top.next;
    }
    return result;
  }

  /**
   * @Description: 栈顶端
   * @return: T
   * @Author: peikunkun
   * @Date: 2020/1/3 0003 下午 4:29
   */
  @Override
  public T peek() {
    if (this.isEmpty()) {
      throw new EmptyStackException();
    }
    return top.item;
  }

  /**
   * @Description: 栈指针是否为空
   * @Param:
   * @return: boolean
   * @Author: peikunkun
   * @Date: 2020/1/3 0003 下午 4:29
   */
  @Override
  public boolean isEmpty() {
    //是否已经是最初初始化的那条链
    return top.end();
  }


  /**
   * -----------------------------------------------------------------------------------------------<br/>
   * Node定义一个节点类,用来储存数据
   *
   * @param <U>
   */
  private static class Node<U> {

    /**
     * 储存数据
     */
    private U item;

    /**
     * 类似指针
     */
    private Node<U> next;

    public Node() {
      this.item = null;
      this.next = null;
    }

    public Node(U item, Node<U> next) {
      this.item = item;
      this.next = next;
    }

    /**
     * @Description: 是否已经
     * @Param:
     * @return: boolean
     * @Author: peikunkun
     * @Date: 2020/1/3 0003 下午 5:01
     */
    boolean end() {
      return item == null && next == null;
    }
  }
}
